package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;

    /**
     * 新增套餐
     */
    @Override
    @Transactional
    public void insert(SetmealDTO setmealDTO) {
        //1.创建套餐类对象
        Setmeal setmeal = new Setmeal();
        //2.给套餐对象赋值
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //3.套餐调用Mapper执行insert语句，需要主键回填，然后将主键绑定给第三方表
        setmealMapper.insert(setmeal);
        //4.获取套餐的菜品集合（必填，一定不为空）
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes();
        //5.给集合每个元素赋值套餐id
        setmealDishList.forEach(smd -> smd.setSetmealId(setmeal.getId()));
        //6.套餐关系表调用Mapper执行insert语句
        setmealDishMapper.insert(setmealDishList);
    }

    /**
     * 分页查询套餐
     */
    @Override
    public PageResult showAll(SetmealPageQueryDTO setmealPageQueryDTO) {
        //1.开启分页并给页数与每页个数
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
        //2.调用Mapper查询全部,因为开启了分页,会自动添加limit
        // TODO: 2023/12/4/0004 模糊查询异常
        List<SetmealVO> setmealList = setmealMapper.showAll(setmealPageQueryDTO);
        //3.获取数据总数,不想再写一个count的SQL,所以强转Page,里面有，且是一个集合
        Page<SetmealVO> page = (Page<SetmealVO>) setmealList;
        /**
         * //2与3一条代码写下来
         * (Page<Setmeal>) setmealList;这里的泛型可加可不加，前面接收类型有
         * Page<Setmeal> page = (Page)setmealMapper.showAll(setmealPageQueryDTO);
         */
        //4.将总数,这页数据封装返回（一次性给）
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 删除套餐
     */
    @Override
    public void delete(List<Long> ids) {
        //1.调用套餐Mapper接口删除套餐
        setmealMapper.delete(ids);
        //2.调用套餐菜品关系Mapper接口删除关联菜品
        setmealDishMapper.delete(ids);
    }

    /**
     * 根据id查询套餐
     */
    @Override
    public SetmealVO selectById(Long id) {
        //1.创建SetmealVO对象
        SetmealVO setmealVO = new SetmealVO();
        //2.setmealMapper的查询
        Setmeal setmeal = setmealMapper.selectById(id);
        //3.查询的值赋值给VO
        BeanUtils.copyProperties(setmeal, setmealVO);
        //4.setmealDish的Mapper查询
        List<SetmealDish> setmealDishList = setmealDishMapper.selectBySetmealId(id);
        //5.查询的值赋值给VO
        setmealVO.setSetmealDishes(setmealDishList);
        return setmealVO;
    }

    /**
     * 修改套餐
     */
    @Override
    @Transactional
    public void update(SetmealDTO setmealDTO) {
        //1.创建Setmeal对象
        Setmeal setmeal = new Setmeal();
        //2.给对象赋值
        BeanUtils.copyProperties(setmealDTO, setmeal);
        //3.执行setmealMapper接口update方法
        setmealMapper.update(setmeal);
        //4.删除SetmealDish关系表的菜品对象。（菜品必填，一定不为空）
        setmealDishMapper.deleteBySetmealId(setmealDTO.getId());
        //5.获取DTO的菜品对象
        List<SetmealDish> setmealDishList = setmealDTO.getSetmealDishes();
        //6.把Setmeal的id赋值给菜品对象
        setmealDishList.forEach(sdl -> sdl.setSetmealId(setmealDTO.getId()));
        //7.setmealMapper执行insert语句新建菜品
        setmealDishMapper.insert(setmealDishList);
    }

    /**
     * 修改套餐状态
     */
    @Override
    public void updateStatus(Integer status, Long id) {
        //1.直接创建对象调用Mapper（少写一个SQL）
        Setmeal setmeal = new Setmeal();
        //2.如果要进行启售，查看是否有关联停售菜品
        if (StatusConstant.ENABLE == status) {
            //2.1根据套餐id获取套餐内菜品状态
            List<Integer> dishStatus = dishMapper.getDishStatus(id);
            //2.2 如果有一个符合就throw new
            dishStatus.forEach(ds -> {
                if (ds == StatusConstant.DISABLE)
                    throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
            });
        }
        //3.停售或者启售套餐没有包含停售的菜品就执行sql
        setmeal.setId(id);
        setmeal.setStatus(status);
        setmealMapper.update(setmeal);
    }

    /**
     * 条件查询
     * @param setmeal
     * @return
     */
    public List<Setmeal> list(Setmeal setmeal) {
        List<Setmeal> list = setmealMapper.list(setmeal);
        return list;
    }

    /**
     * 根据id查询菜品选项
     * @param id
     * @return
     */
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }
}
